Advanced Data Journalism Final Project

Data from: https://ephtracking.cdc.gov/DataExplorer/?c=35&i=88&m=-1

https://ephtracking.cdc.gov/DataExplorer/?c=35&i=88&m=-1

https://public.tableau.com/app/profile/samantha2462/viz/shared/437ZHKXJZ

https://moboscoc.org/resources/data/point-in-time-count-reports/

Step 1: Load libraries

library(plotly)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout

Step 2: Load data

We will be using three data sets. One contains the coordinates and details for cooling centers serving Missouri and the other contains heat-related hospitalizations over the last several years. I also loaded population data from the Census.

coolingcenters <- read_csv("Final Project/Missouri_Cooling_Centers_Sites.csv")

heathospitalizations <- read_csv("Final Project/heatrate.csv")

hud_mo <- read_csv("Final Project/HUDmo.csv")

Step 3: Clean data

Clean & organize cooling centers data.

Our data needs to be properly — and specifically — formatted so it can be easily visualized.

#First, I'm separating the latitude and longitude into separate boxes. 
coolingcentersclean <- coolingcenters %>% 
  separate(Location, sep=", ", into=c("latitude", "longitude"))

#I'm also cleaning up these boxes by removing the parentheses from them.
coolingcentersclean <- coolingcentersclean %>%
 mutate(lat = str_replace(latitude, "[(]", ""))

coolingcentersclean <- coolingcentersclean %>%
 mutate(long = str_replace(longitude, "[)]", ""))

#I'm going to change the state abbreviations to their names so it will be easier to combine with the states data.
coolingcentersclean <- coolingcentersclean %>% mutate(region = case_when(
  grepl("MO", state, ignore.case=T) ~ "missouri",
  grepl("IL", state, ignore.case=T) ~ "illinois",
  grepl("KS", state, ignore.case=T) ~ "kansas"))

#I'm going to remove the improperly formatting latitude and longitude from the dataset. 
coolingcentersclean <- subset (coolingcentersclean, select = -latitude)
coolingcentersclean <- subset (coolingcentersclean, select = -longitude)

#We'll need our coordinates to be numbers so we can plot them.
coolingcentersclean$lat <- as.numeric(coolingcentersclean$lat)
coolingcentersclean$long <- as.numeric(coolingcentersclean$long)

#Lastly, I'll be cleaning the names with janitor. 
coolingcentersclean <- clean_names(coolingcentersclean)

Clean & organize heat data

#This dataset is relatively clean, so I'm just going to clean the names and then remove the column at the end.
heathospitalizations <- clean_names(heathospitalizations)
heathosptializations <- tolower(heathospitalizations$state)

heathospitalizations <- subset (heathospitalizations, select = -x6)

Clean & organize county pop data

county_pop  <- clean_names(county_pop)
county_pop <- county_pop %>% separate(name, sep=",", into=c("county", "state"))
county_pop <- county_pop %>%  mutate(county = str_replace(county, " County", ""))

Clean & organize projected heat data

projectedheat <- clean_names(projectedheat)

Clean & organize HUD data

Step 4: Load map data

states <- map_data("state") %>% filter(region=="missouri" | region == "illinois" | region == "kansas")

statescounties <- map_data("county") %>% filter(region ==  "missouri" | region == "illinois" | region == "kansas")

mocounties <- map_data("county") %>% filter(region ==  "missouri")

countiesall <- map_data("county")

Step 5: Create custom interactive dot map

By using county-level data from the maps package and plotly, we can create our own custom interactive dot map.

staticdotmap_ <- ggplot(statescounties, aes(x = long, y = lat, group = group)) +
  geom_polygon(fill = "#F8F9F9", color = "darkgray", linewidth=.1) +
  geom_point(data=coolingcentersclean, aes(group = NULL, text = paste("Location:", facility)),   alpha=.5, size=.7, color="#EE9253") +   
  coord_fixed(1.3) +
  theme_void() +
  labs(title="Cooling Centers in Missouri", caption = "Data from data.mo.gov") + theme_void()

staticdotmap <- ggplotly(staticdotmap_, tooltip = "text")

Step 6: Create interactive dot map with leaflet

Leaflet is a simpler way to plot data interactively.

interactivedotmap <- leaflet() %>% 
    addProviderTiles(providers$CartoDB.Positron) %>%
    addCircleMarkers(
    data = coolingcentersclean,
    color = "#EE9253",
    opacity = 0.5,
    radius = 1,
    ~long, ~lat, popup = ~htmlEscape(facility))

Step 8: Create an interactive bar graph

Similar to how we created a custom interactive dot map, we can do the same for bar graphs.

#I'm going to create a tooltip first to make the bar graph interactive. 
heathospitalizations <- heathospitalizations %>% mutate(
    tooltip_text = paste0(year, " - ", value, "%"))

#Now, I'm going to use ggplot to create the bar graph.
bar_graph_ <- heathospitalizations %>% 
  filter(state=="Missouri") %>% 
  ggplot(aes(x=year, y=value, tooltip = tooltip_text, data_id = state)) + 
  geom_col_interactive(width=.7, fill="#EE9253", size = 0.2) + 
  theme_minimal() +
  theme(axis.text=element_text(size = 7), axis.title=element_text(size=7),        title=element_text(size=7)) +
   labs(title = "Percentage of heat-related illness hospitalizations in Missouri per 100k people",subtitle = "Data from CDC") +
   ylab("Percentage of heat hospitalizations") +
   xlab("Year") +
  geom_hline(yintercept = 2.010133,color="red", linewidth=.5)
  
#Girafe will let us make the graph interactive.
bar_graph <- girafe(ggobj = bar_graph_, width_svg = 5, height_svg = 3)
chloro_map <- girafe(ggobj = chloro_map, width_svg = 5, height_svg = 3)
Error:
! `ggobj` must be a ggplot2 plot
Backtrace:
 1. ggiraph::girafe(ggobj = chloro_map, width_svg = 5, height_svg = 3)

Step 9: Some basic analysis

coolingcentersclean %>% 
  filter(transportation == "Yes")
#No centers provide transportation

coolingcentersclean %>% 
  filter(ada_accessible == "No")
#All centers are ADA accessible

coolingcentersclean %>% 
  group_by(county) %>% 
  count(county) %>% 
  arrange(desc(n))
#Jackson County has the most cooling centers followed by St. Louis county and then Madison

coolingcentersclean %>% 
  filter(county == "Boone")
#Boone County has 6 cooling centers

coolingcentersclean %>% 
  filter(grepl("sun", hours_of_operation, ignore.case=T))
#58 centers are open on Sundays

heathospitalizations %>% 
  arrange(desc(value))
#California had the highest heat-related hospitalization rate in 2020; Missouri had the sixth highest rate in 2011 at 7.6.

heathospitalizations %>% 
  filter(state=="Missouri") %>% 
  arrange(desc(value))
#Missouri had its highest number of heat-related hospitalizations in 2011

heathospitalizations %>% 
  summarise(average = mean(value))
#The average percentage of heat-related illness hospitalizations from 2000 to 2021 using availble data was 2.010133%.

heathospitalizations %>% 
  group_by(state) %>% 
  summarise(average = mean(value)) %>% 
  arrange(desc(average))
#Missouri has the second highest rate of the data reported. 

projectedheat %>% 
  group_by(state) %>%
  summarise(average=mean(value)) %>% 
  arrange(desc(average))
#Missouri ranks tenth in "projected difference in extreme heat days as compared to the historical period" with an average across the state of about 24 days. 

Story Package

Important statistics and data analysis to include in the story:

In the last two decades, Missouri ranks in the top ten out of reporting states for the highest rate of heat-related illnesses per 100,000 people. In 2011, the rate in Missouri reached 7.6%, ranking it number 6 behind Arizona.

Missouri currently reports 538 cooling centers. 58 of those cooling centers are open on Sundays.

Graphs to include in the story:

animatedgraph

bar_graph + 
  transition_states(year,
  transition_length = 2,
  state_length = 1) +
  ease_aes('sine-in-out')
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyAqKkFkdmFuY2VkIERhdGEgSm91cm5hbGlzbSBGaW5hbCBQcm9qZWN0KioKCkRhdGEgZnJvbTogPGh0dHBzOi8vZXBodHJhY2tpbmcuY2RjLmdvdi9EYXRhRXhwbG9yZXIvP2M9MzUmaT04OCZtPS0xPgoKPGh0dHBzOi8vZXBodHJhY2tpbmcuY2RjLmdvdi9EYXRhRXhwbG9yZXIvP2M9MzUmaT04OCZtPS0xPgoKPGh0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL2FwcC9wcm9maWxlL3NhbWFudGhhMjQ2Mi92aXovc2hhcmVkLzQzN1pIS1hKWj4KCmh0dHBzOi8vbW9ib3Njb2Mub3JnL3Jlc291cmNlcy9kYXRhL3BvaW50LWluLXRpbWUtY291bnQtcmVwb3J0cy8KCgojIyMgU3RlcCAxOiBMb2FkIGxpYnJhcmllcwoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkobWFwcykKbGlicmFyeShzZikKbGlicmFyeShsZWFmbGV0KQpsaWJyYXJ5KHNwRGF0YSkKbGlicmFyeSh0aWR5Y2Vuc3VzKQpsaWJyYXJ5KGdnaXJhcGgpCmxpYnJhcnkocGxvdGx5KQoKI0FuaW1hdGlvbiBMaWJyYXJpZXMKbGlicmFyeShnZ2FuaW1hdGUpCmxpYnJhcnkoc3ApCmxpYnJhcnkodmlyaWRpcykKbGlicmFyeShodG1sdG9vbHMpCmxpYnJhcnkoZ2FwbWluZGVyKQpsaWJyYXJ5KGdpZnNraSkKbGlicmFyeShwbmcpCmxpYnJhcnkodG1hcCkKCgpgYGAKCiMjIyBTdGVwIDI6IExvYWQgZGF0YQoKV2Ugd2lsbCBiZSB1c2luZyB0aHJlZSBkYXRhIHNldHMuIE9uZSBjb250YWlucyB0aGUgY29vcmRpbmF0ZXMgYW5kIGRldGFpbHMgZm9yIGNvb2xpbmcgY2VudGVycyBzZXJ2aW5nIE1pc3NvdXJpIGFuZCB0aGUgb3RoZXIgY29udGFpbnMgaGVhdC1yZWxhdGVkIGhvc3BpdGFsaXphdGlvbnMgb3ZlciB0aGUgbGFzdCBzZXZlcmFsIHllYXJzLiBJIGFsc28gbG9hZGVkIHBvcHVsYXRpb24gZGF0YSBmcm9tIHRoZSBDZW5zdXMuCgpgYGB7cn0KY29vbGluZ2NlbnRlcnMgPC0gcmVhZF9jc3YoIkZpbmFsIFByb2plY3QvTWlzc291cmlfQ29vbGluZ19DZW50ZXJzX1NpdGVzLmNzdiIpCgpoZWF0aG9zcGl0YWxpemF0aW9ucyA8LSByZWFkX2NzdigiRmluYWwgUHJvamVjdC9oZWF0cmF0ZS5jc3YiKQoKaHVkX21vIDwtIHJlYWRfY3N2KCJGaW5hbCBQcm9qZWN0L0hVRG1vLmNzdiIpCmBgYAoKIyMjIFN0ZXAgMzogQ2xlYW4gZGF0YQoKQ2xlYW4gJiBvcmdhbml6ZSBjb29saW5nIGNlbnRlcnMgZGF0YS4KCk91ciBkYXRhIG5lZWRzIHRvIGJlIHByb3Blcmx5IC0tLSBhbmQgc3BlY2lmaWNhbGx5IC0tLSBmb3JtYXR0ZWQgc28gaXQgY2FuIGJlIGVhc2lseSB2aXN1YWxpemVkLgoKYGBge3J9CiNGaXJzdCwgSSdtIHNlcGFyYXRpbmcgdGhlIGxhdGl0dWRlIGFuZCBsb25naXR1ZGUgaW50byBzZXBhcmF0ZSBib3hlcy4gCmNvb2xpbmdjZW50ZXJzY2xlYW4gPC0gY29vbGluZ2NlbnRlcnMgJT4lIAogIHNlcGFyYXRlKExvY2F0aW9uLCBzZXA9IiwgIiwgaW50bz1jKCJsYXRpdHVkZSIsICJsb25naXR1ZGUiKSkKCiNJJ20gYWxzbyBjbGVhbmluZyB1cCB0aGVzZSBib3hlcyBieSByZW1vdmluZyB0aGUgcGFyZW50aGVzZXMgZnJvbSB0aGVtLgpjb29saW5nY2VudGVyc2NsZWFuIDwtIGNvb2xpbmdjZW50ZXJzY2xlYW4gJT4lCiBtdXRhdGUobGF0ID0gc3RyX3JlcGxhY2UobGF0aXR1ZGUsICJbKF0iLCAiIikpCgpjb29saW5nY2VudGVyc2NsZWFuIDwtIGNvb2xpbmdjZW50ZXJzY2xlYW4gJT4lCiBtdXRhdGUobG9uZyA9IHN0cl9yZXBsYWNlKGxvbmdpdHVkZSwgIlspXSIsICIiKSkKCiNJJ20gZ29pbmcgdG8gY2hhbmdlIHRoZSBzdGF0ZSBhYmJyZXZpYXRpb25zIHRvIHRoZWlyIG5hbWVzIHNvIGl0IHdpbGwgYmUgZWFzaWVyIHRvIGNvbWJpbmUgd2l0aCB0aGUgc3RhdGVzIGRhdGEuCmNvb2xpbmdjZW50ZXJzY2xlYW4gPC0gY29vbGluZ2NlbnRlcnNjbGVhbiAlPiUgbXV0YXRlKHJlZ2lvbiA9IGNhc2Vfd2hlbigKICBncmVwbCgiTU8iLCBzdGF0ZSwgaWdub3JlLmNhc2U9VCkgfiAibWlzc291cmkiLAogIGdyZXBsKCJJTCIsIHN0YXRlLCBpZ25vcmUuY2FzZT1UKSB+ICJpbGxpbm9pcyIsCiAgZ3JlcGwoIktTIiwgc3RhdGUsIGlnbm9yZS5jYXNlPVQpIH4gImthbnNhcyIpKQoKI0knbSBnb2luZyB0byByZW1vdmUgdGhlIGltcHJvcGVybHkgZm9ybWF0dGluZyBsYXRpdHVkZSBhbmQgbG9uZ2l0dWRlIGZyb20gdGhlIGRhdGFzZXQuIApjb29saW5nY2VudGVyc2NsZWFuIDwtIHN1YnNldCAoY29vbGluZ2NlbnRlcnNjbGVhbiwgc2VsZWN0ID0gLWxhdGl0dWRlKQpjb29saW5nY2VudGVyc2NsZWFuIDwtIHN1YnNldCAoY29vbGluZ2NlbnRlcnNjbGVhbiwgc2VsZWN0ID0gLWxvbmdpdHVkZSkKCiNXZSdsbCBuZWVkIG91ciBjb29yZGluYXRlcyB0byBiZSBudW1iZXJzIHNvIHdlIGNhbiBwbG90IHRoZW0uCmNvb2xpbmdjZW50ZXJzY2xlYW4kbGF0IDwtIGFzLm51bWVyaWMoY29vbGluZ2NlbnRlcnNjbGVhbiRsYXQpCmNvb2xpbmdjZW50ZXJzY2xlYW4kbG9uZyA8LSBhcy5udW1lcmljKGNvb2xpbmdjZW50ZXJzY2xlYW4kbG9uZykKCiNMYXN0bHksIEknbGwgYmUgY2xlYW5pbmcgdGhlIG5hbWVzIHdpdGggamFuaXRvci4gCmNvb2xpbmdjZW50ZXJzY2xlYW4gPC0gY2xlYW5fbmFtZXMoY29vbGluZ2NlbnRlcnNjbGVhbikKYGBgCgpDbGVhbiAmIG9yZ2FuaXplIGhlYXQgZGF0YQoKYGBge3J9CiNUaGlzIGRhdGFzZXQgaXMgcmVsYXRpdmVseSBjbGVhbiwgc28gSSdtIGp1c3QgZ29pbmcgdG8gY2xlYW4gdGhlIG5hbWVzIGFuZCB0aGVuIHJlbW92ZSB0aGUgY29sdW1uIGF0IHRoZSBlbmQuCmhlYXRob3NwaXRhbGl6YXRpb25zIDwtIGNsZWFuX25hbWVzKGhlYXRob3NwaXRhbGl6YXRpb25zKQpoZWF0aG9zcHRpYWxpemF0aW9ucyA8LSB0b2xvd2VyKGhlYXRob3NwaXRhbGl6YXRpb25zJHN0YXRlKQoKaGVhdGhvc3BpdGFsaXphdGlvbnMgPC0gc3Vic2V0IChoZWF0aG9zcGl0YWxpemF0aW9ucywgc2VsZWN0ID0gLXg2KQpgYGAKCkNsZWFuICYgb3JnYW5pemUgY291bnR5IHBvcCBkYXRhCgpgYGB7cn0KY291bnR5X3BvcCAgPC0gY2xlYW5fbmFtZXMoY291bnR5X3BvcCkKY291bnR5X3BvcCA8LSBjb3VudHlfcG9wICU+JSBzZXBhcmF0ZShuYW1lLCBzZXA9IiwiLCBpbnRvPWMoImNvdW50eSIsICJzdGF0ZSIpKQpjb3VudHlfcG9wIDwtIGNvdW50eV9wb3AgJT4lICBtdXRhdGUoY291bnR5ID0gc3RyX3JlcGxhY2UoY291bnR5LCAiIENvdW50eSIsICIiKSkKYGBgCgpDbGVhbiAmIG9yZ2FuaXplIHByb2plY3RlZCBoZWF0IGRhdGEKCmBgYHtyfQpwcm9qZWN0ZWRoZWF0IDwtIGNsZWFuX25hbWVzKHByb2plY3RlZGhlYXQpCmBgYAoKQ2xlYW4gJiBvcmdhbml6ZSBIVUQgZGF0YQpgYGB7cn0KaHVkX21vIDwtIGNsZWFuX25hbWVzKGh1ZF9tbykKaHVkX21vIDwtIGh1ZF9tbyAlPiUgcmVuYW1lKHVuc2hlbHRlcmVkX3RvdGFsID0gbWVhc3VyZV92YWx1ZXMpCmBgYAoKIyMjIFN0ZXAgNDogTG9hZCBtYXAgZGF0YQoKYGBge3J9CnN0YXRlcyA8LSBtYXBfZGF0YSgic3RhdGUiKSAlPiUgZmlsdGVyKHJlZ2lvbj09Im1pc3NvdXJpIiB8IHJlZ2lvbiA9PSAiaWxsaW5vaXMiIHwgcmVnaW9uID09ICJrYW5zYXMiKQoKc3RhdGVzY291bnRpZXMgPC0gbWFwX2RhdGEoImNvdW50eSIpCgptb2NvdW50aWVzIDwtIG1hcF9kYXRhKCJjb3VudHkiKSAlPiUgZmlsdGVyKHJlZ2lvbiA9PSAgIm1pc3NvdXJpIikKCmNvdW50aWVzYWxsIDwtIG1hcF9kYXRhKCJjb3VudHkiKQpgYGAKCiMjIyBTdGVwIDU6IENyZWF0ZSBjdXN0b20gaW50ZXJhY3RpdmUgZG90IG1hcApCeSB1c2luZyBjb3VudHktbGV2ZWwgZGF0YSBmcm9tIHRoZSBtYXBzIHBhY2thZ2UgYW5kIHBsb3RseSwgd2UgY2FuIGNyZWF0ZSBvdXIgb3duIGN1c3RvbSBpbnRlcmFjdGl2ZSBkb3QgbWFwLgoKYGBge3J9CnN0YXRpY2RvdG1hcF8gPC0gZ2dwbG90KHN0YXRlc2NvdW50aWVzLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApKSArCiAgZ2VvbV9wb2x5Z29uKGZpbGwgPSAiI0Y4RjlGOSIsIGNvbG9yID0gImRhcmtncmF5IiwgbGluZXdpZHRoPS4xKSArCiAgZ2VvbV9wb2ludChkYXRhPWNvb2xpbmdjZW50ZXJzY2xlYW4sIGFlcyhncm91cCA9IE5VTEwsIHRleHQgPSBwYXN0ZSgiTG9jYXRpb246IiwgZmFjaWxpdHkpKSwgICBhbHBoYT0uNSwgc2l6ZT0uNywgY29sb3I9IiNFRTkyNTMiKSArICAgCiAgY29vcmRfZml4ZWQoMS4zKSArCiAgdGhlbWVfdm9pZCgpICsKICBsYWJzKHRpdGxlPSJDb29saW5nIENlbnRlcnMgaW4gTWlzc291cmkiLCBjYXB0aW9uID0gIkRhdGEgZnJvbSBkYXRhLm1vLmdvdiIpICsgdGhlbWVfdm9pZCgpCgpzdGF0aWNkb3RtYXAgPC0gZ2dwbG90bHkoc3RhdGljZG90bWFwXywgdG9vbHRpcCA9ICJ0ZXh0IikKYGBgCgojIyMgU3RlcCA2OiBDcmVhdGUgaW50ZXJhY3RpdmUgZG90IG1hcCB3aXRoIGxlYWZsZXQKTGVhZmxldCBpcyBhIHNpbXBsZXIgd2F5IHRvIHBsb3QgZGF0YSBpbnRlcmFjdGl2ZWx5LiAKCmBgYHtyfQppbnRlcmFjdGl2ZWRvdG1hcCA8LSBsZWFmbGV0KCkgJT4lIAogICAgYWRkUHJvdmlkZXJUaWxlcyhwcm92aWRlcnMkQ2FydG9EQi5Qb3NpdHJvbikgJT4lCiAgICBhZGRDaXJjbGVNYXJrZXJzKAogICAgZGF0YSA9IGNvb2xpbmdjZW50ZXJzY2xlYW4sCiAgICBjb2xvciA9ICIjRUU5MjUzIiwKICAgIG9wYWNpdHkgPSAwLjUsCiAgICByYWRpdXMgPSAxLAogICAgfmxvbmcsIH5sYXQsIHBvcHVwID0gfmh0bWxFc2NhcGUoZmFjaWxpdHkpKQpgYGAKCiMjIyBTdGVwIDg6IENyZWF0ZSBhbiBpbnRlcmFjdGl2ZSBiYXIgZ3JhcGgKU2ltaWxhciB0byBob3cgd2UgY3JlYXRlZCBhIGN1c3RvbSBpbnRlcmFjdGl2ZSBkb3QgbWFwLCB3ZSBjYW4gZG8gdGhlIHNhbWUgZm9yIGJhciBncmFwaHMuCgpgYGB7cn0KI0knbSBnb2luZyB0byBjcmVhdGUgYSB0b29sdGlwIGZpcnN0IHRvIG1ha2UgdGhlIGJhciBncmFwaCBpbnRlcmFjdGl2ZS4gCmhlYXRob3NwaXRhbGl6YXRpb25zIDwtIGhlYXRob3NwaXRhbGl6YXRpb25zICU+JSBtdXRhdGUoCiAgICB0b29sdGlwX3RleHQgPSBwYXN0ZTAoeWVhciwgIiAtICIsIHZhbHVlLCAiJSIpKQoKI05vdywgSSdtIGdvaW5nIHRvIHVzZSBnZ3Bsb3QgdG8gY3JlYXRlIHRoZSBiYXIgZ3JhcGguCmJhcl9ncmFwaF8gPC0gaGVhdGhvc3BpdGFsaXphdGlvbnMgJT4lIAogIGZpbHRlcihzdGF0ZT09Ik1pc3NvdXJpIikgJT4lIAogIGdncGxvdChhZXMoeD15ZWFyLCB5PXZhbHVlLCB0b29sdGlwID0gdG9vbHRpcF90ZXh0LCBkYXRhX2lkID0gc3RhdGUpKSArIAogIGdlb21fY29sX2ludGVyYWN0aXZlKHdpZHRoPS43LCBmaWxsPSIjRUU5MjUzIiwgc2l6ZSA9IDAuMikgKyAKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZSA9IDcpLCBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTcpLCAgICAgICAgdGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9NykpICsKICAgbGFicyh0aXRsZSA9ICJQZXJjZW50YWdlIG9mIGhlYXQtcmVsYXRlZCBpbGxuZXNzIGhvc3BpdGFsaXphdGlvbnMgaW4gTWlzc291cmkgcGVyIDEwMGsgcGVvcGxlIixzdWJ0aXRsZSA9ICJEYXRhIGZyb20gQ0RDIikgKwogICB5bGFiKCJQZXJjZW50YWdlIG9mIGhlYXQgaG9zcGl0YWxpemF0aW9ucyIpICsKICAgeGxhYigiWWVhciIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyLjAxMDEzMyxjb2xvcj0icmVkIiwgbGluZXdpZHRoPS41KQogIAojR2lyYWZlIHdpbGwgbGV0IHVzIG1ha2UgdGhlIGdyYXBoIGludGVyYWN0aXZlLgpiYXJfZ3JhcGggPC0gZ2lyYWZlKGdnb2JqID0gYmFyX2dyYXBoXywgd2lkdGhfc3ZnID0gNSwgaGVpZ2h0X3N2ZyA9IDMpCgpgYGAKCgpgYGB7cn0KaHVkX3N0YXRlcyA8LSAKICBodWRfbW8gJT4lIAogIG11dGF0ZShjb3VudHkgPSBzdHJfdG9fbG93ZXIoY291bnR5KSkgJT4lIAogIHJpZ2h0X2pvaW4obW9jb3VudGllcywgYnkgPSBjKCJjb3VudHkiID0gInN1YnJlZ2lvbiIpKQoKY2hsb3JvX21hcCA8LWdncGxvdChodWRfc3RhdGVzLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXAsIGZpbGwgPSB1bnNoZWx0ZXJlZF90b3RhbCkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGdlb21fcG9seWdvbihjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAuMSkgKwogIGNvb3JkX2ZpeGVkKDEuMykgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdyA9ICIjRkVGOUU3IiwgbWlkID0gIiNGNEQwM0YiLCBoaWdoID0gIiM3RDY2MDgiKSArCiAgbGFicyh0aXRsZSA9ICJIVUQgVGl0bGUiLHN1YnRpdGxlID0gIkRhdGEgZnJvbSBDREMiKSArCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gJyNGOEY5RjknLCBjb2xvciA9ICcjRjhGOUY5JykpCmBgYAoKIyMjIFN0ZXAgOTogU29tZSBiYXNpYyBhbmFseXNpcwoKYGBge3J9CmNvb2xpbmdjZW50ZXJzY2xlYW4gJT4lIAogIGZpbHRlcih0cmFuc3BvcnRhdGlvbiA9PSAiWWVzIikKI05vIGNlbnRlcnMgcHJvdmlkZSB0cmFuc3BvcnRhdGlvbgoKY29vbGluZ2NlbnRlcnNjbGVhbiAlPiUgCiAgZmlsdGVyKGFkYV9hY2Nlc3NpYmxlID09ICJObyIpCiNBbGwgY2VudGVycyBhcmUgQURBIGFjY2Vzc2libGUKCmNvb2xpbmdjZW50ZXJzY2xlYW4gJT4lIAogIGdyb3VwX2J5KGNvdW50eSkgJT4lIAogIGNvdW50KGNvdW50eSkgJT4lIAogIGFycmFuZ2UoZGVzYyhuKSkKI0phY2tzb24gQ291bnR5IGhhcyB0aGUgbW9zdCBjb29saW5nIGNlbnRlcnMgZm9sbG93ZWQgYnkgU3QuIExvdWlzIGNvdW50eSBhbmQgdGhlbiBNYWRpc29uCgpjb29saW5nY2VudGVyc2NsZWFuICU+JSAKICBmaWx0ZXIoY291bnR5ID09ICJCb29uZSIpCiNCb29uZSBDb3VudHkgaGFzIDYgY29vbGluZyBjZW50ZXJzCgpjb29saW5nY2VudGVyc2NsZWFuICU+JSAKICBmaWx0ZXIoZ3JlcGwoInN1biIsIGhvdXJzX29mX29wZXJhdGlvbiwgaWdub3JlLmNhc2U9VCkpCiM1OCBjZW50ZXJzIGFyZSBvcGVuIG9uIFN1bmRheXMKCmhlYXRob3NwaXRhbGl6YXRpb25zICU+JSAKICBhcnJhbmdlKGRlc2ModmFsdWUpKQojQ2FsaWZvcm5pYSBoYWQgdGhlIGhpZ2hlc3QgaGVhdC1yZWxhdGVkIGhvc3BpdGFsaXphdGlvbiByYXRlIGluIDIwMjA7IE1pc3NvdXJpIGhhZCB0aGUgc2l4dGggaGlnaGVzdCByYXRlIGluIDIwMTEgYXQgNy42LgoKaGVhdGhvc3BpdGFsaXphdGlvbnMgJT4lIAogIGZpbHRlcihzdGF0ZT09Ik1pc3NvdXJpIikgJT4lIAogIGFycmFuZ2UoZGVzYyh2YWx1ZSkpCiNNaXNzb3VyaSBoYWQgaXRzIGhpZ2hlc3QgbnVtYmVyIG9mIGhlYXQtcmVsYXRlZCBob3NwaXRhbGl6YXRpb25zIGluIDIwMTEKCmhlYXRob3NwaXRhbGl6YXRpb25zICU+JSAKICBzdW1tYXJpc2UoYXZlcmFnZSA9IG1lYW4odmFsdWUpKQojVGhlIGF2ZXJhZ2UgcGVyY2VudGFnZSBvZiBoZWF0LXJlbGF0ZWQgaWxsbmVzcyBob3NwaXRhbGl6YXRpb25zIGZyb20gMjAwMCB0byAyMDIxIHVzaW5nIGF2YWlsYmxlIGRhdGEgd2FzIDIuMDEwMTMzJS4KCmhlYXRob3NwaXRhbGl6YXRpb25zICU+JSAKICBncm91cF9ieShzdGF0ZSkgJT4lIAogIHN1bW1hcmlzZShhdmVyYWdlID0gbWVhbih2YWx1ZSkpICU+JSAKICBhcnJhbmdlKGRlc2MoYXZlcmFnZSkpCiNNaXNzb3VyaSBoYXMgdGhlIHNlY29uZCBoaWdoZXN0IHJhdGUgb2YgdGhlIGRhdGEgcmVwb3J0ZWQuIAoKcHJvamVjdGVkaGVhdCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUpICU+JQogIHN1bW1hcmlzZShhdmVyYWdlPW1lYW4odmFsdWUpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGF2ZXJhZ2UpKQojTWlzc291cmkgcmFua3MgdGVudGggaW4gInByb2plY3RlZCBkaWZmZXJlbmNlIGluIGV4dHJlbWUgaGVhdCBkYXlzIGFzIGNvbXBhcmVkIHRvIHRoZSBoaXN0b3JpY2FsIHBlcmlvZCIgd2l0aCBhbiBhdmVyYWdlIGFjcm9zcyB0aGUgc3RhdGUgb2YgYWJvdXQgMjQgZGF5cy4gCgpgYGAKCiMjIyBTdG9yeSBQYWNrYWdlCgoqKkltcG9ydGFudCBzdGF0aXN0aWNzIGFuZCBkYXRhIGFuYWx5c2lzIHRvIGluY2x1ZGUgaW4gdGhlIHN0b3J5OioqCgpJbiB0aGUgbGFzdCB0d28gZGVjYWRlcywgTWlzc291cmkgcmFua3MgaW4gdGhlIHRvcCB0ZW4gb3V0IG9mIHJlcG9ydGluZyBzdGF0ZXMgZm9yIHRoZSBoaWdoZXN0IHJhdGUgb2YgaGVhdC1yZWxhdGVkIGlsbG5lc3NlcyBwZXIgMTAwLDAwMCBwZW9wbGUuIEluIDIwMTEsIHRoZSByYXRlIGluIE1pc3NvdXJpIHJlYWNoZWQgNy42JSwgcmFua2luZyBpdCBudW1iZXIgNiBiZWhpbmQgQXJpem9uYS4KCk1pc3NvdXJpIGN1cnJlbnRseSByZXBvcnRzIDUzOCBjb29saW5nIGNlbnRlcnMuIDU4IG9mIHRob3NlIGNvb2xpbmcgY2VudGVycyBhcmUgb3BlbiBvbiBTdW5kYXlzLiAKCioqR3JhcGhzIHRvIGluY2x1ZGUgaW4gdGhlIHN0b3J5OioqCgpgYGB7cn0Kc3RhdGljZG90bWFwCmBgYApgYGB7cn0KaW50ZXJhY3RpdmVkb3RtYXAKYGBgCmBgYHtyfQpiYXJfZ3JhcGgKYGBgCmBgYHtyfQpjaGxvcm9fbWFwCmBgYAoKYGBge3J9CmFuaW1hdGVkZ3JhcGgKCmJhcl9ncmFwaCArIAogIHRyYW5zaXRpb25fc3RhdGVzKHllYXIsCiAgdHJhbnNpdGlvbl9sZW5ndGggPSAyLAogIHN0YXRlX2xlbmd0aCA9IDEpICsKICBlYXNlX2Flcygnc2luZS1pbi1vdXQnKQpgYGAK